'''
Created on Mar 16, 2013

@author: Gabriel
'''
import simplejson
import random
import xbmc
import xbmcgui
import urllib2
import PyDbLite
import os
import datetime
import time

_tempDir = _data_path = xbmc.translatePath("special://temp").decode("utf-8")

class _Persistent(object) :
    # Global instance of the database to be used everywhere around
    _DB_RECORD = None
    _DATA_OBJECT = None

    # Database record manager
    _db = None
    _databaseName = None
    _dataObjectName = None
    # Type of object to be saved. Either a dictionary, or a list or something else
    _defaultDataObject = None

    def __init__(self, databaseName, dataObjectName, defaultDataObject={}):
        self._databaseName = databaseName
        self._dataObjectName = dataObjectName
        self._defaultDataObject = defaultDataObject
        self.load()

    def _erase(self):
        print ('DELETING DB')
        self._db.drop()


    def unload(self):
        self._db = None
        self._DB_RECORD = None
        self._DATA_OBJECT = None

    def load(self):
        self._db = PyDbLite.Base(self._databaseName)
        self._db.create(self._dataObjectName, mode='open')
        if len(self._db) == 0:
            print (self._db.insert(self._defaultDataObject))
            self._db.commit()
#        else :
#            self._erase()

#        print ('Current database: ' + self._dataObjectName)
#        for rec in self._db:
#            print (rec)
        self._DB_RECORD = self._db[0]
        self._DATA_OBJECT = self._DB_RECORD[self._dataObjectName]
    
    
    def _save(self):
        self._db.update(self._DB_RECORD, **{self._dataObjectName : self._DATA_OBJECT})
        self._db.commit()    

    def reset(self):
        self._erase()
        self.load()

    def download(self, url):
        tempfile = _tempDir + self._databaseName + '.json'
        if os.path.exists(tempfile):
            os.remove(tempfile)
        u = urllib2.urlopen(url)
        f = open(tempfile, "w")
        f.write(u.read())
        f.close()
        if os.path.exists(tempfile):
            f = open(tempfile, 'r')
            self._DATA_OBJECT = simplejson.load(f)
            f.close()
        else :
            self._DATA_OBJECT = {}
        self._save()


class DatabaseMgr(_Persistent) :

    def __init__(self):
        super(DatabaseMgr, self).__init__("videosDatabase", "videos")

    def __randomIndex(self, array):
        return random.randint(0, len(array) - 1)
        
    # Queries
    def getRandomMovieEntry(self):
        randomMovie = self._DATA_OBJECT['movies'][self.__randomIndex(self._DATA_OBJECT['movies'])]
        return randomMovie["name"]
    
    
    def getRandomEpisodePath(self):
        randomShow = self._DATA_OBJECT['shows'][self.__randomIndex(self._DATA_OBJECT['shows'])]
        randomEpisode = randomShow['episodes'][self.__randomIndex(randomShow['episodes'])]
        return randomEpisode
    
    def __seekVideoInCategory(self, videoName, category):
        for video in self._DATA_OBJECT[category] : 
            print video['name']
            if str(video['name']) == str(videoName) :
                return video
            
            
    def getEpisodePath(self, videoName, episodeNumber):
        print("getEpisodePath")
        print(videoName)
        print(episodeNumber)
        video = self.__seekVideoInCategory(videoName, 'shows')
        if not video :
            video = self.__seekVideoInCategory(videoName, 'movies')
        # Gets the path to the current episode
        return video['episodes'][episodeNumber]
    
    #
    # Returns the number of episodes
    #
    def getEpisodeCount(self, seriesName):
        video = self.__seekVideoInCategory(seriesName, 'shows')
        if not video :
            video = self.__seekVideoInCategory(seriesName, 'movies')
        return len(video['episodes'])

    def getShowsForDisplay(self):
        showNames = []
        for show in self._DATA_OBJECT['shows']:
            showNames.append(str(show['name']))
        return showNames


class ScheduleMgr(_Persistent) :
    _TEMPLATE_SCHEDULE_ROW = ["<show>", "<show>", "<show>", "<show>", "<show>", "<show>", "<show>"]
    
    def __init__(self):
        super(ScheduleMgr, self).__init__("scheduleMgr", "schedule")
        self._dummySchedule()
        self._save()
    
    def __sortKeys(self) :
        print(self._DATA_OBJECT)
        sortedKeys = self._DATA_OBJECT.keys()
        sortedKeys.sort()
        return sortedKeys
        
    def _dummySchedule(self):
        if len(self._DATA_OBJECT.keys()) == 0:
            print("Creating new schedule")
            self._DATA_OBJECT["07:00"] = self._TEMPLATE_SCHEDULE_ROW

    def __getDatetime(self, timeStr):
        return datetime.datetime(*(time.strptime(timeStr, '%H:%M')[0:6]))

    def __getTime(self, timeStr):
        return self.__getDatetime(timeStr).time()
    
    def __getScheduleEntryForTime(self, ptime):
        previousEntry = None
        selectedEntry = None
        for entry in self.__sortKeys():
            if previousEntry:
                intervalStart = self.__getTime(previousEntry)
                intervalEnd = self.__getTime(entry)
                if (intervalStart < ptime and ptime < intervalEnd) : 
                    print("Schedule entry for time")
                    print(ptime)
                    print(previousEntry)
                    selectedEntry = previousEntry
            previousEntry = entry
        # block to include the last interval between the last entry and 24:00 hours
        if selectedEntry == None : 
            selectedEntry = previousEntry
        return selectedEntry


    def getScheduleRowCount(self):
        return len(self._DATA_OBJECT.keys())

    def addNextRow(self, currentTime):
        nextEntryTime = self.__getDatetime(currentTime) + datetime.timedelta(minutes=30)
        self._DATA_OBJECT[nextEntryTime.strftime("%H:%M")] = list(self._DATA_OBJECT[currentTime])
        self._save()
        
    def removeRow(self, desiredTime):
        self._DATA_OBJECT.pop(desiredTime)
        self._save()

    def getScheduleForDisplay(self):
        preparedSchedule = []
        for key in self.__sortKeys():
            rowItem = xbmcgui.ListItem()
            rowItem.setLabel(str(key))
            rowItem.setProperty('isTime', 'True')
            rowItem.setProperty('time', str(key))
            preparedSchedule.append(rowItem)
            for day, entry in enumerate(self._DATA_OBJECT[key]) :
                rowItem = xbmcgui.ListItem()
                rowItem.setLabel(str(entry))
                rowItem.setProperty('time', str(key))
                rowItem.setProperty('day', str(day))
                preparedSchedule.append(rowItem)
        return preparedSchedule

    def updateScheduleTimeEntry(self, newTime, time):
        entryTime = self.__getDatetime(newTime.strip())
        formattedNewTime = entryTime.strftime("%H:%M")
        self._DATA_OBJECT[formattedNewTime] = self._DATA_OBJECT.pop(time)
        self._save()
        
        
    def updateScheduleEntry(self, newValue, time, day):
        self._DATA_OBJECT[time][int(day)] = newValue
        self._save()
        
    def getNextScheduleEntry(self):
        now = datetime.datetime.now().time()
        weekday = datetime.datetime.now().weekday()
        currentScheduleEntry = self.__getScheduleEntryForTime(now)
        playNext = self._DATA_OBJECT[currentScheduleEntry][weekday]
        print("Getting entry for:")
        print(weekday)
        print(currentScheduleEntry)
        return playNext


class EpisodeMgr(_Persistent) :

    def __init__(self):
        super(EpisodeMgr, self).__init__("episodeMgr", "series", [])
        # self._DATA_OBJECT=[{'name':'Seinfeld', 'currentEpisode':2},{'name':'Woddy', 'currentEpisode':3}]

    def getCurrentEpisode(self, seriesName):
        currentEpisode = 0
        for series in self._DATA_OBJECT : 
            if series['name'] == seriesName :
                currentEpisode = series['currentEpisode']
        return currentEpisode
    
    #
    # Increments the current episode and overflows back to initial episode
    #
    def incrementCurrentEpisode(self, seriesName, episodesCount):
        print("Incrementing episode: " + seriesName)
        nextEpisode = (self.getCurrentEpisode(seriesName) + 1) % episodesCount 
        self.setCurrentEpisode(seriesName, nextEpisode)

    def getEpisodeCountersForDisplay(self):
        preparedEpisodeCounters = []
        for series in self._DATA_OBJECT: 
            print series
            rowItem = xbmcgui.ListItem()
            rowItem.setLabel(str(series['name']))
            rowItem.setLabel2(str(series['currentEpisode']))
            preparedEpisodeCounters.append(rowItem)
        return preparedEpisodeCounters

    def setCurrentEpisode(self, seriesName, currentEpisode):
        updatedSerie = {'name':seriesName, 'currentEpisode': currentEpisode}
        print(updatedSerie)
        existingIndex = None
        for index, series in enumerate(self._DATA_OBJECT) : 
            if series['name'] == seriesName :
                existingIndex = index
                break
        if existingIndex != None:
            self._DATA_OBJECT[existingIndex] = updatedSerie
        else :
            self._DATA_OBJECT.append(updatedSerie)
        self._save()
        print (self._DATA_OBJECT)
